 // main.c -- Defines the C-code kernel entry point, calls initialisation routines.
//           Made for JamesM's tutorials <www.jamesmolloy.co.uk>

#include <monitor.h>
#include <descriptor_tables.h>
#include <timer.h>
#include <paging.h>
#include <multiboot.h>
#include <fs.h>
#include <initrd.h>
#include <task.h>
#include <syscall.h>
#include <video.h>
#include <version.h>
#include <panic.h>

extern u32int placement_address;
u32int initial_esp;

int main(struct multiboot *mboot_ptr, u32int initial_stack)
{
	swich_to_8x8_mode();
	// Initialise the screen (by clearing it)
	monitor_clear();

    printf("NasuTek Ensemble Version %s.%s (Build %s)", MAJOR_VERSION, MINOR_VERSION, BUILD_VERSION);
    #ifdef SERVICEPACK_VERSION
    printf(" Service Pack %s", SERVICEPACK_VERSION);
    #endif
    printf("\nCopyright (C) 2008-%s NasuTek Systems\n", YEAR_VERSION);
    printf("[%dMB Physical Memory] [1 Logical Processor In Use By OS]\n", mboot_ptr->mem_upper/1024);
    printf("Kernel compiled with GCC v.%s on %s %s\n\n", __VERSION__, __DATE__, __TIME__);

    initial_esp = initial_stack;
    // Initialise all the ISRs and segmentation
    init_descriptor_tables();
   
    // Initialise the PIT to 100Hz
    asm volatile("sti");
    init_timer(50);

    // Find the location of our initial ramdisk.
    ASSERT(mboot_ptr->mods_count > 0);
    u32int initrd_location = *((u32int*)mboot_ptr->mods_addr);
    u32int initrd_end = *(u32int*)(mboot_ptr->mods_addr+4);
    // Don't trample our module with placement accesses, please!
    placement_address = initrd_end;

    // Start paging.
    initialise_paging();

    // Start multitasking.
    initialise_tasking();

    // Initialise the initial ramdisk, and set it as the filesystem root.
    fs_root = initialise_initrd(initrd_location);

    initialise_syscalls();

    switch_to_user_mode();

    //syscall_monitor_write("Hello, user world!\n");

    return 0;
}
